home *** CD-ROM | disk | FTP | other *** search
/ X User Tools / X User Tools (O'Reilly and Associates)(1994).ISO / sources / xless / xless141.z / xless141 / xless-1.4.1 / init.c < prev    next >
C/C++ Source or Header  |  1993-04-30  |  14KB  |  457 lines

  1. /*
  2.  * Copyright 1989 Massachusetts Institute of Technology
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and its
  5.  * documentation for any purpose and without fee is hereby granted, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of M.I.T. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  M.I.T. makes no representations about the
  11.  * suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  15.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  16.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  17.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  18.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  19.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  20.  *
  21.  * Author: Carlo Lisa
  22.  *       MIT Project Athena
  23.  *       carlo@athena.mit.edu
  24.  *
  25.  * $Header: /usr/sww/share/src/X11R5/local/clients/xless-1.4/RCS/init.c,v 1.27 1993/04/30 18:36:56 dglo Exp $
  26.  */
  27.  
  28. #include "xless.h"
  29.  
  30. /*
  31.  *    Function Name: InitData
  32.  *    Description:   This function reads a file and sets it up for
  33.  *               display in the asciiTextWidget.
  34.  *    Arguments:     file - a file pointer to the file that we are opening.
  35.  *    Returns:       data - a pointer to the data read from the file
  36.  *                  and stored in dynamic memory.
  37.  */
  38.  
  39. static int dataheight, datawidth;
  40.  
  41. const char *
  42. InitData(file)
  43. FILE *file;
  44. {
  45.   char *data;        /* pointer to the data stored
  46.                in dynamic memory */
  47.   struct stat fileinfo;    /* file information from fstat */
  48.   int sz, newsz;        /* # of chars fread has written into data */
  49.   char *tmp, *where;
  50.   int i, w;
  51.  
  52.   /*
  53.    * Get file size and allocate a chunk of memory for the file to be
  54.    * copied into.
  55.    */
  56.  
  57.   if (file == stdin) {
  58.  
  59.     /* create an initial memory buffer */
  60.     if ((data = (char *) malloc(MEMBUF)) == NULL) {
  61.       fprintf(stderr, "xless: not enough memory available.\n");
  62.       exit(1);
  63.     }
  64.  
  65.     /* read STDIN a chunk at a time */
  66.     fileinfo.st_size = 0;
  67.     where = data;
  68.     while ((sz = fread(where, sizeof(char), MEMBUF, file)) != 0) {
  69.       fileinfo.st_size += sz;
  70.       /* remember old data in case of realloc failure */
  71.       tmp = data;
  72.       newsz = fileinfo.st_size+MEMBUF;
  73.       if ((data = (char *)realloc(data, (unsigned)newsz)) == NULL) {
  74.     fprintf(stderr, "xless: not enough memory available.\n");
  75.     data = tmp;
  76.     break;
  77.       }
  78.       where = data + fileinfo.st_size;
  79.     }
  80.  
  81.     /* see if file ends with a NEWLINE */
  82.     if (*(data + fileinfo.st_size - 1) != '\n')
  83.       fileinfo.st_size++;
  84.  
  85.     /* allocate final chunk of memory */
  86.     tmp = data;
  87.     newsz = fileinfo.st_size + 1;
  88.     if ((data = (char *)realloc(data, (unsigned)newsz)) == NULL) {
  89.       fprintf(stderr, "xless: not enough memory available.\n");
  90.       data = tmp;
  91.     }
  92.  
  93.     /* make sure file ends with a NEWLINE */
  94.     if (*(data + fileinfo.st_size - 1) != '\n')
  95.       *(data + fileinfo.st_size - 1) = '\n';
  96.  
  97.   } else {
  98.  
  99.     /* get size of file */
  100.     if (fstat(fileno(file), &fileinfo)) {
  101.       fprintf(stderr, "xless: can't get file size.\n");
  102.       exit(1);
  103.     }
  104.  
  105.     /* leave space for the NULL (and possibly a final NEWLINE) */
  106.     if ((data = (char *) malloc(fileinfo.st_size + 2)) == NULL) {
  107.       fprintf(stderr, "xless: not enough memory available.\n");
  108.       exit(1);
  109.     }
  110.  
  111.     /* read file in one swoop */
  112.     fread(data, sizeof(char), fileinfo.st_size, file);
  113.     fclose(file);
  114.  
  115.     /* make sure file ends with a NEWLINE */
  116.     if (*(data + fileinfo.st_size - 1) != '\n') {
  117.       *(data + fileinfo.st_size) = '\n';
  118.       fileinfo.st_size++;
  119.     }
  120.   }
  121.  
  122.   /* NUL-terminate file string */
  123.   *(data + fileinfo.st_size) = '\0';
  124.  
  125.   /* lose all underlined and bold characters in the file */
  126.   i = w = 0;
  127.   dataheight = datawidth = 0;
  128.   tmp = data;
  129.   while (i < fileinfo.st_size) {
  130.     if ((*(data + i) == '_') && (*(data + i + 1) == '\b')) {
  131.       i += 2;
  132.     } else if ((*(data + i) == *(data + i + 2)) &&
  133.            (*(data + i + 1) == '\b')) {
  134.       i += 2;
  135.     } else {
  136.       *tmp = *(data + i++);
  137.       if (*tmp == '\n') {
  138.     if (w > datawidth)
  139.       datawidth = w;
  140.     w = 0;
  141.     dataheight++;
  142.       } else
  143.     w++;
  144.       tmp++;
  145.     }
  146.   }
  147.   *tmp = 0;
  148.  
  149.   return(data);
  150. }
  151.  
  152. static Widget
  153. makeButton(parent, sensitive, vertdist, prevwidg, procptr, wininfo,
  154.        accelstr, label)
  155. Widget parent;
  156. Boolean sensitive;
  157. int vertdist;
  158. Widget prevwidg;
  159. XtCallbackProc procptr;
  160. WindowInfo *wininfo;
  161. String accelstr;
  162. const char *label;
  163. {
  164.   Arg args[14];
  165.   Cardinal i;
  166.   XtCallbackRec callback[2];
  167.   Widget w;
  168.   XtAccelerators accel;
  169.  
  170.   i = 0;
  171.   if (sensitive) {
  172.     XtSetArg(args[i], XtNsensitive, False); i++;
  173.   }
  174.   XtSetArg(args[i], XtNfont, buttonfont); i++;
  175.   XtSetArg(args[i], XtNcursor, stdcur); i++;
  176.   XtSetArg(args[i], XtNwidth, BUTTONWIDTH); i++;
  177.   XtSetArg(args[i], XtNvertDistance, vertdist); i++;
  178.   XtSetArg(args[i], XtNhorizDistance, 4); i++;
  179.   XtSetArg(args[i], XtNfromVert, prevwidg); i++;
  180.   XtSetArg(args[i], XtNfromHoriz, NULL); i++;
  181.   XtSetArg(args[i], XtNtop, XtChainTop); i++;
  182.   XtSetArg(args[i], XtNbottom, XtChainTop); i++;
  183.   XtSetArg(args[i], XtNright, XtChainLeft); i++;
  184.   XtSetArg(args[i], XtNleft, XtChainLeft); i++;
  185.   callback[0].callback = procptr;
  186.   callback[0].closure = (XtPointer )wininfo;
  187.   callback[1].callback = (XtCallbackProc) NULL;
  188.   callback[1].closure = (XtPointer) NULL;
  189.   XtSetArg(args[i], XtNcallback, callback); i++;
  190.   accel = XtParseAcceleratorTable(accelstr);
  191.   XtSetArg(args[i], XtNaccelerators, accel); i++;
  192.   w = XtCreateManagedWidget(label, commandWidgetClass, parent, args, i);
  193.   XtInstallAccelerators(wininfo->text, w);
  194.   return(w);
  195. }
  196.  
  197. /*
  198.  *    Function Name: MakeToolbox
  199.  *    Description:   This function create all the widgets necessary
  200.  *               to build the toolbox.
  201.  *    Arguments:     parent   - the parent widget
  202.  *               cd       - pointer to the data structure containing
  203.  *                      the application data.
  204.  *               notmain  - TRUE if this is not the main window
  205.  *               new_wdg  - the shell widget that is the new window
  206.  *               filename - the name of the file displayed in the window
  207.  *    Returns:       None.
  208.  */
  209.  
  210. Widget
  211. MakeToolbox(parent, wi, filename)
  212. Widget parent;
  213. WindowInfo *wi;
  214. const char *filename;
  215. {
  216.   Arg args[15];
  217.   Cardinal i;
  218.   Widget box, button;
  219.   const String AccSearch = "#override Meta<Key>S:   set() notify() unset()\n";
  220.   const String AccNext = "#override Meta<Key>N:   set() notify() unset()\n";
  221.   const String AccReload = "#override Meta<Key>R:   set() notify() unset()\n";
  222.   const String AccEdit = "#override Meta<Key>E:   set() notify() unset()\n";
  223.   const String AccChange = "#override Meta<Key>C:   set() notify() unset()\n";
  224.   const String AccWind = "#override Meta<Key>W:   set() notify() unset()\n";
  225.   const String AccPrint = "#override Meta<Key>P: set() notify() unset()\n";
  226.   const String AccHelp = "#override <Key>?: set() notify() unset()\n";
  227.   const String AccClose = "#override <Key>Q: set() notify() unset()\n";
  228.   const String AccQuit = "#override Meta<Key>Q: set() notify() unset()\n";
  229.  
  230.   /* create the ButtonBox which contains the toolbox */
  231.   i = 0;
  232.   XtSetArg(args[i], XtNallowResize, True); i++;
  233.   XtSetArg(args[i], XtNskipAdjust, True); i++;
  234.   XtSetArg(args[i], XtNhorizDistance, 1); i++;
  235.   XtSetArg(args[i], XtNfromHoriz, wi->text); i++;
  236.   XtSetArg(args[i], XtNtop, XtChainTop); i++;
  237.   XtSetArg(args[i], XtNbottom, XtChainTop); i++;
  238.   XtSetArg(args[i], XtNright, XtChainRight); i++;
  239.   XtSetArg(args[i], XtNleft, XtChainRight); i++;
  240.   XtSetArg(args[i], XtNorientation, XtorientVertical); i++;
  241.   XtSetArg(args[i], XtNshowGrip, False); i++;
  242.   box = XtCreateManagedWidget("toolbox", boxWidgetClass, parent,
  243.                   args, i);
  244.  
  245.   button = (Widget )NULL;
  246.   button = makeButton(box, FALSE, 1, button, PopupHelp, wi, AccHelp, "Help");
  247.   button = makeButton(box, FALSE, 1, button, Search, wi, AccSearch, "Search");
  248.   button = makeButton(box, FALSE, 1, button, SearchNext, wi,
  249.               AccNext, "Search Next");
  250.   button = makeButton(box, (filename == NULL ? TRUE : FALSE), 1, button,
  251.               CallEditor, wi, AccEdit, "Editor");
  252.   if (filename == NULL)
  253.     wi->editor_button = button;
  254.   else
  255.     wi->editor_button = 0;
  256.   button = makeButton(box, (filename == NULL ? TRUE : FALSE), 1, button,
  257.               Reload, wi, AccReload, "Reload");
  258.   if (filename == NULL)
  259.     wi->reload_button = button;
  260.   else
  261.     wi->reload_button = 0;
  262.   button = makeButton(box, FALSE, 1, button, ChangeFile, wi,
  263.               AccChange, "Change file");
  264.   button = makeButton(box, FALSE, 1, button, NewWindow, wi,
  265.               AccWind, "New window");
  266.   button = makeButton(box, FALSE, 1, button, Print, wi, AccPrint, "Print");
  267.   button = makeButton(box, FALSE, 1, button, CloseWindow, wi, AccClose,
  268.               "Close window");
  269.   if (resources.quitButton)
  270.     button = makeButton(box, FALSE, 1, button, Quit, wi, AccQuit, "Quit");
  271.  
  272.   return(box);
  273. }
  274.  
  275. /*
  276.  *    Function Name: MakeText
  277.  *    Description:   This function creates the text widget necessary
  278.  *               to display the data.
  279.  *    Arguments:     parent - the parent widget
  280.  *               data   - pointer to data in memory.
  281.  *    Returns:       tmp    - the text widget so created.
  282.  */
  283.  
  284. Widget
  285. MakeText(parent, data)
  286. Widget parent;
  287. const char *data;
  288. {
  289.   static int width, height;
  290.   Widget txt;
  291.   Arg args[16];
  292.   Cardinal i = 0;
  293.  
  294.   /* get defaults for text window width&height */
  295.   if (width == 0) {
  296.     int mask, xoffset, yoffset;
  297.     int window_width, window_height;
  298.     int char_width, char_height;
  299.  
  300.     /* get geometry from resource */
  301.     mask = XParseGeometry(resources.textGeometry, &xoffset, &yoffset,
  302.               &window_width, &window_height);
  303.     if ((mask & WidthValue) == 0 || (mask & HeightValue) == 0 ||
  304.     window_width <= 0 || window_height <= 0) {
  305.       printf("Bad textGeometry \"%s\"!\n", resources.textGeometry);
  306.       window_width = 80;
  307.       window_height = 24;
  308.     }
  309.  
  310.     /* get width/height of a text window character */
  311.     char_width = textfont->max_bounds.width;
  312.     char_height = textfont->ascent + textfont->descent;
  313.  
  314.     /* if actual text is smaller, use it instead */
  315.     if (resources.sizeToFit) {
  316.       if (window_width > datawidth)
  317.     window_width = datawidth + 1;
  318.       if (window_height > dataheight)
  319.     window_height = dataheight;
  320.     }
  321.  
  322.     /* find width/height of text window in pixels */
  323.     width = window_width * char_width;
  324.     height = window_height * char_height;
  325.   }
  326.  
  327.   XtSetArg(args[i], XtNstring, data); i++;
  328.   XtSetArg(args[i], XtNscrollVertical, XawtextScrollWhenNeeded); i++;
  329.   XtSetArg(args[i], XtNscrollHorizontal, XawtextScrollWhenNeeded); i++;
  330.   XtSetArg(args[i], XtNwidth, width); i++;
  331.   XtSetArg(args[i], XtNheight, height); i++;
  332.   XtSetArg(args[i], XtNallowResize, True); i++;
  333.   XtSetArg(args[i], XtNskipAdjust, False); i++;
  334.   XtSetArg(args[i], XtNfont, textfont); i++;
  335.   XtSetArg(args[i], XtNhorizDistance, 1); i++;
  336.   XtSetArg(args[i], XtNfromHoriz, NULL); i++;
  337.   XtSetArg(args[i], XtNtop, XtChainTop); i++;
  338.   XtSetArg(args[i], XtNbottom, XtChainBottom); i++;
  339.   XtSetArg(args[i], XtNright, XtChainRight); i++;
  340.   XtSetArg(args[i], XtNleft, XtChainLeft); i++;
  341.   XtSetArg(args[i], XtNdisplayNonprinting, False); i++;
  342.   XtSetArg(args[i], XtNshowGrip, False); i++;
  343.   txt = XtCreateManagedWidget("text", asciiTextWidgetClass,
  344.                   parent, args, i);
  345.  
  346.   return (txt);
  347. }
  348.  
  349. void
  350. SetXNames(top, filename)
  351. Widget top;
  352. const char *filename;
  353. {
  354.   static int namelen = 0;
  355.   static char *namestr = 0;
  356.   const char *namePrefix = resources.namePrefix;
  357.   const char *cp;
  358.   int prefixlen, newlen;
  359.   Cardinal i;
  360.   Arg args[2];
  361.  
  362.   /* make sure there's a filename string */
  363.   if (!filename || *filename == 0)
  364.     return;
  365.  
  366.   /* figure out how long the prefix is */
  367.   if (namePrefix && *namePrefix)
  368.     prefixlen = strlen(namePrefix);
  369.   else
  370.     prefixlen = 0;
  371.  
  372.   /* remove path junk if user doesn't want it */
  373.   if (resources.removePath) {
  374.     cp = strrchr(filename, '/');
  375.     if (cp)
  376.       filename = cp + 1;
  377.   }
  378.  
  379.   /* make sure name buffer is large enough */
  380.   newlen = prefixlen + strlen(filename) + 1;
  381.   if (newlen > namelen) {
  382.     if (namestr)
  383.       free(namestr);
  384.     namestr = (char *)malloc(newlen);
  385.     namelen = newlen;
  386.   }
  387.  
  388.   /* create title/icon name string */
  389.   strcpy(namestr, namePrefix);
  390.   strcat(namestr, filename);
  391.  
  392.   /* set window's icon and title names to the file name */
  393.   i = 0;
  394.   XtSetArg(args[i], XtNiconName, namestr); i++;
  395.   XtSetArg(args[i], XtNtitle, namestr); i++;
  396.   XtSetValues(top, args, i);
  397. }
  398.  
  399. void
  400. SetWMHints(wi)
  401. WindowInfo *wi;
  402. {
  403.   Dimension txt_width, txt_height;
  404.   Dimension win_width, win_height;
  405.   Dimension base_width, base_height;
  406.   int char_width, char_height;
  407.   Cardinal i = 0;
  408.   Arg args[6];
  409.  
  410.   /* get width/height of entire window */
  411.   XtVaGetValues(wi->base,
  412.         XtNwidth, &win_width,
  413.         XtNheight, &win_height,
  414.         NULL);
  415.  
  416.   /* get width/height of text window */
  417.   XtVaGetValues(wi->text,
  418.         XtNwidth, &txt_width,
  419.         XtNheight, &txt_height,
  420.         NULL);
  421.  
  422.   /* get width/height of a text window character */
  423.   char_width = textfont->max_bounds.width;
  424.   char_height = textfont->ascent + textfont->descent;
  425.  
  426.   /* figure out base width/height */
  427.   base_width = win_width - txt_width;
  428.   base_height = win_height - txt_height;
  429.  
  430.   /* set base size */
  431.   XtSetArg(args[i], XtNbaseWidth, base_width); i++;
  432.   XtSetArg(args[i], XtNbaseHeight, base_height); i++;
  433.  
  434.   /* set increment size */
  435.   XtSetArg(args[i], XtNwidthInc, char_width); i++;
  436.   XtSetArg(args[i], XtNheightInc, char_height); i++;
  437.  
  438.   /* get size of button box */
  439.   XtVaGetValues(wi->toolbox,
  440.         XtNwidth, &win_width,
  441.         XtNheight, &win_height,
  442.         NULL);
  443.  
  444.   /* guess at size of a 1x1 text window */
  445.   txt_width = base_width + char_width;
  446.   txt_height = base_height + char_height;
  447.  
  448.   /* set minimum window size */
  449.   XtSetArg(args[i], XtNminWidth,
  450.        txt_width > win_width ? txt_width : win_width); i++;
  451.   XtSetArg(args[i], XtNminHeight,
  452.        txt_height > win_height ? txt_height : win_height); i++;
  453.  
  454.   /* set hints */
  455.   XtSetValues(wi->base, args, i);
  456. }
  457.